using System.Collections.Concurrent;
using System.Threading;

namespace muduoDotNet
{
    /// <summary>
    /// 事件循环类，是Reactor模式的核心组件
    /// </summary>
    public class EventLoop : IDisposable
    {
        private readonly CancellationTokenSource _cancellationTokenSource;
        private Thread? _loopThread;
        private readonly ConcurrentQueue<Action> _pendingTasks;
        private readonly ManualResetEventSlim _wakeupEvent;
        private readonly Poller _poller;
        private readonly TimerQueue _timerQueue;
        private bool _running;
        private bool _disposed;

        public EventLoop()
        {
            _cancellationTokenSource = new CancellationTokenSource();
            _pendingTasks = new ConcurrentQueue<Action>();
            _wakeupEvent = new ManualResetEventSlim(false);
            _poller = Poller.NewDefaultPoller(this);
            _timerQueue = new TimerQueue(this);
            _running = false;
            _disposed = false;
            _loopThread = null; // 将在Start()中创建
        }

        /// <summary>
        /// 启动事件循环
        /// </summary>
        public void Start()
        {
            if (_running)
            {
                throw new NetException("EventLoop is already running");
            }
            
            _running = true;
            _loopThread = new Thread(Loop) { Name = "EventLoop" };
            _loopThread.Start();
        }

        /// <summary>
        /// 停止事件循环
        /// </summary>
        public void Stop()
        {
            if (!_running)
            {
                return;
            }
            
            _running = false;
            _cancellationTokenSource.Cancel();
            _wakeupEvent.Set();
            
            if (_loopThread != null && _loopThread.IsAlive)
            {
                _loopThread.Join(5000); // 5秒超时
            }
        }

        /// <summary>
        /// 在事件循环线程中执行任务
        /// </summary>
        /// <param name="action">要执行的任务</param>
        public void RunInLoop(Action action)
        {
            if (IsInLoopThread())
            {
                action();
            }
            else
                {
                QueueInLoop(action);
            }
        }

        /// <summary>
        /// 将任务加入队列，在事件循环线程中执行
        /// </summary>
        /// <param name="action">要执行的任务</param>
        public void QueueInLoop(Action action)
        {
            _pendingTasks.Enqueue(action);
            Logger.Debug($"Task queued, current thread: {Thread.CurrentThread.ManagedThreadId}, loop thread: {_loopThread?.ManagedThreadId ?? -1}");
            
            // 始终唤醒事件循环，确保任务能被处理
            Wakeup();
        }

        
        /// <summary>
        /// 唤醒事件循环
        /// </summary>
        private void Wakeup()
        {
            _wakeupEvent.Set();
        }
        
        /// <summary>
        /// 计算轮询超时时间
        /// </summary>
        /// <returns>超时时间（毫秒）</returns>
        private int GetPollTimeoutMs()
        {
            var nearestExpiration = _timerQueue.GetNearestExpiration();
            
            if (!nearestExpiration.IsValid)
            {
                // 没有定时器，检查是否有待处理任务
                if (!_pendingTasks.IsEmpty)
                {
                    return 0; // 立即返回处理任务
                }
                return 10; // 10ms
            }
            
            var now = TimeStamp.Now();
            if (nearestExpiration <= now)
            {
                // 已经过期，不等待
                return 0;
            }
            
            // 计算剩余时间
            var timeoutSeconds = nearestExpiration.SecondsSinceEpoch - now.SecondsSinceEpoch;
            var timeoutMs = (int)(timeoutSeconds * 1000);
            
            // 限制最大超时时间，并确保至少为1ms
            return Math.Min(Math.Max(timeoutMs, 1), 1000); // 1ms 到 1秒
        }

        /// <summary>
        /// 检查当前线程是否是事件循环线程
        /// </summary>
        /// <returns>如果是事件循环线程则返回true</returns>
        public bool IsInLoopThread()
        {
            return _loopThread != null && Thread.CurrentThread == _loopThread;
        }

        /// <summary>
        /// 断言当前线程是事件循环线程
        /// </summary>
        public void AssertInLoopThread()
        {
            if (!IsInLoopThread())
            {
                throw new NetException("Not in loop thread");
            }
        }

        /// <summary>
        /// 更新Channel在Poller中的注册
        /// </summary>
        /// <param name="channel">要更新的Channel</param>
        public void UpdateChannel(Channel channel)
        {
            AssertInLoopThread();
            _poller.UpdateChannel(channel);
        }

        /// <summary>
        /// 从 Poller 中移除 Channel
        /// </summary>
        /// <param name="channel">要移除的Channel</param>
        public void RemoveChannel(Channel channel)
        {
            AssertInLoopThread();
            _poller.RemoveChannel(channel);
        }
        
        /// <summary>
        /// 添加定时器
        /// </summary>
        /// <param name="callback">定时器回调</param>
        /// <param name="delaySeconds">延迟秒数</param>
        /// <param name="intervalSeconds">间隔秒数，0表示一次性定时器</param>
        /// <returns>TimerId对象</returns>
        public TimerId AddTimer(Action callback, double delaySeconds, double intervalSeconds = 0.0)
        {
            if (IsInLoopThread())
            {
                return _timerQueue.AddTimer(callback, delaySeconds, intervalSeconds);
            }
            else
            {
                TimerId result = default;
                var resetEvent = new ManualResetEventSlim();
                RunInLoop(() =>
                {
                    result = _timerQueue.AddTimer(callback, delaySeconds, intervalSeconds);
                    resetEvent.Set();
                });
                resetEvent.Wait();
                resetEvent.Dispose();
                return result;
            }
        }
        
        /// <summary>
        /// 取消定时器
        /// </summary>
        /// <param name="timerId">要取消的TimerId</param>
        public void CancelTimer(TimerId timerId)
        {
            _timerQueue.Cancel(timerId);
        }

        /// <summary>
        /// 事件循环的主要逻辑
        /// </summary>
        private void Loop()
        {
            if (Thread.CurrentThread != _loopThread)
            {
                throw new NetException("Loop should be called in loop thread");
            }

            // 设置线程本地存储
            ThreadLocalEventLoop.SetEventLoop(this);
            Logger.Debug($"EventLoop started in thread {Thread.CurrentThread.ManagedThreadId}");

            try
            {
                while (_running)
                {
                    // 记录开始时间用于性能监控
                    var startTime = DateTime.UtcNow;
                    
                    // 先处理所有待执行的任务
                    DoPendingTasks();

                    // 处理定时器
                    var now = TimeStamp.Now();
                    var expiredTimers = _timerQueue.GetExpiredTimers(now);
                    foreach (var timer in expiredTimers)
                    {
                        try
                        {
                            timer.Run();
                            // 更新定时器执行计数器
                            PerformanceCounters.IncrementTimersExecuted();
                        }
                        catch (Exception ex)
                        {
                            Logger.Error("Exception in timer callback", ex);
                            PerformanceCounters.IncrementTotalExceptions();
                        }
                    }

                    // 计算轮询超时时间
                    int timeoutMs = GetPollTimeoutMs();
                    
                    // 进行IO多路复用，等待IO事件
                    var activeChannels = _poller.Poll(timeoutMs);
                    
                    // 处理活跃的Channel
                    foreach (var channel in activeChannels)
                    {
                        try
                        {
                            channel.HandleEvent();
                        }
                        catch (Exception ex)
                        {
                            Logger.Error($"Exception in channel event handling for fd {channel.Fd}", ex);
                            PerformanceCounters.IncrementTotalExceptions();
                        }
                        finally
                        {
                            // 清除已处理的事件
                            channel.Revents = EventType.None;
                        }
                    }
                    
                    // 记录处理时间用于性能监控
                    var endTime = DateTime.UtcNow;
                    var processingTimeMs = (long)(endTime - startTime).TotalMilliseconds;
                    PerformanceCounters.RecordProcessingTime(processingTimeMs);
                    PerformanceCounters.IncrementEventLoopIterations();
                    
                    // 改进的等待机制
                    if (_running)
                    {                        
                        // 检查是否有定时器即将过期
                        var nextExpiration = _timerQueue.GetNearestExpiration();
                        if (nextExpiration.IsValid && nextExpiration <= TimeStamp.Now())
                        {
                            continue; // 有定时器过期，继续循环
                        }
                        
                        // 如果有待处理任务，不等待，直接继续下一轮循环
                        if (!_pendingTasks.IsEmpty)
                        {
                            continue;
                        }
                        
                        // 重置唤醒事件
                        _wakeupEvent.Reset();
                        
                        // 等待被唤醒或超时
                        try
                        {
                            _wakeupEvent.Wait(Math.Min(timeoutMs, 50), _cancellationTokenSource.Token);
                        }
                        catch (OperationCanceledException)
                        {
                            break;
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                // 预期的取消异常，无需处理
                Logger.Debug("EventLoop cancelled");
            }
            finally
            {
                // 确保处理剩余的任务
                DoPendingTasks();
                
                // 清除线程本地存储
                ThreadLocalEventLoop.ClearEventLoop();
                Logger.Debug($"EventLoop stopped in thread {Thread.CurrentThread.ManagedThreadId}");
            }
        }
        
        /// <summary>
        /// 处理待执行的任务
        /// </summary>
        private void DoPendingTasks()
        {
            var tasksToExecute = new List<Action>();
            
            // 批量取出任务，否避在执行过程中被新任务干扰
            while (_pendingTasks.TryDequeue(out var task))
            {
                tasksToExecute.Add(task);
            }
            
            if (tasksToExecute.Count > 0)
            {
                Logger.Debug($"Processing {tasksToExecute.Count} tasks in EventLoop thread {Thread.CurrentThread.ManagedThreadId}");
                
                foreach (var task in tasksToExecute)
                {
                    try
                    {
                        task();
                        // 更新任务执行计数器
                        PerformanceCounters.IncrementTasksExecuted();
                    }
                    catch (Exception ex)
                    {
                        Logger.Error("Exception in event loop task", ex);
                        PerformanceCounters.IncrementTotalExceptions();
                    }
                }
                
                Logger.Debug($"Completed {tasksToExecute.Count} tasks in EventLoop");
            }
        }

        public void Dispose()
        {
            if (!_disposed)
            {
                _disposed = true;
                Stop();
                _cancellationTokenSource.Dispose();
                _wakeupEvent.Dispose();
                _poller.Dispose();
                _timerQueue.Dispose();
            }
        }
    }
}